// 
// task.h - Defines the structures and prototypes needed to multitask.
//          Written for JamesM's kernel development tutorials.
//

#ifndef TASK_H
#define TASK_H

#include "../../tools/headers/common.h"
#include "../../memory/headers/paging.h"
#include "../../adt/headers/queue.h"
#include "../../api/headers/io.h"
#include "../../adt/headers/linked_list.h"
#define STACK_LOCATION 0xBF000000
#define INITIAL_STACK_SIZE 0xF0000

#define READY 1
#define BLOCKED 2
#define KILLED 3

#define N_OF_RES_TYPES 4

#define RES_TIME 0
#define RES_PROC_EXIT 1
#define RES_QUEUE 2
#define RES_LIST 3


struct resource_struct
{
	u32int id;
	u32int param;
};
typedef struct resource_struct resource_type;


// This structure defines a 'task' - a process.
struct task_struct
{
    int id;                // Process ID.
    u32int esp, ebp;       // Stack and base pointers.
    u32int eip;            // Instruction pointer.
    page_directory_t *page_directory; // Page directory.
    queue_type* input_stream;
	virtual_console_type* console;
	resource_type required_resource;
	u32int state;
	u8int last_error;
    //struct task_struct *next;     // The next task in a linked list.
};
typedef struct task_struct task_t;

typedef BOOL(*resource_check_t)(u32int);



BOOL resource_is_available(resource_type* res);
void block_process(task_t* task, u32int res_id, u32int param);
void initialise_resource_management();

// Initialises the tasking system.
void initialise_tasking();

// Called by the timer hook, this changes the running process.
void task_switch();

// Forks the current process, spawning a new one with a different
// memory space.
int fork();

// Causes the current process' stack to be forcibly moved to a new location.
void move_stack(void *new_stack_start, u32int size);

// Returns the pid of the current process.
int getpid();

#endif
